home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / lib / tex / TeX-spell.el < prev    next >
Encoding:
Text File  |  1987-03-12  |  21.7 KB  |  661 lines

  1. ;;
  2. ;; This file, "TeX-spell.el", is a subsystem of "TeX-mode.el".
  3. ;;
  4. ;; Copyright (C) 1986, 1987    Pehong Chen (phc@renoir.berkeley.edu)
  5. ;; -- Please send bugs and comments to the above address
  6. ;;
  7. ;; <DISCLAIMER>
  8. ;; This program is still under development.  Neither the author nor 
  9. ;; Berkeley VorTeX group accepts responsibility to anyone for the consequences
  10. ;; of using it or for whether it serves any particular purpose or works at all.
  11. ;;
  12.  
  13. (defconst tex-spell-dict-buff "--- TeX Dictionary ---")
  14. (defconst tex-spell-help-buff "--- TeX Spelling Help ---")
  15. (defconst tex-spell-error-buff "--- TeX Spelling Errors ---")
  16. (defconst tex-spell-hsl-suffix ".hsl"
  17.   "Default filename extension for hashed spelling list.")
  18. (defconst tex-spell-usl-suffix ".usl"
  19.   "Default filename extension for unhashed spelling list.")
  20.  
  21. (defun tex-spell-document (&optional prefix)
  22.   "Check spelling of every file included in current document.
  23. With prefix argument, check spelling using a customized hashed spelling list,
  24. if any, without query.  A customized hashed spelling list is either current
  25. document master filename base concatenated with \".hsl\", or the file
  26. bound to the variable tex-hsl-default."
  27.   (interactive "P")
  28.   (tex-check-master-file)
  29.   (tex-check-document-type)
  30.   (tex-get-include-files)
  31.   (let ((lst tex-include-files)
  32.     (asknot nil)
  33.     msg fn fnnd)
  34.     (catch 'finish
  35.       (while lst
  36.     (save-excursion
  37.       (set-buffer (find-file-noselect (setq fn (car lst))))
  38.       (setq msg (concat "Checking " tex-current-type " spelling for entire document"))
  39.       (setq fnnd (file-name-nondirectory fn))
  40.       (setq lst (append (tex-get-input-files msg fnnd) (cdr lst)))
  41.       (if (or asknot
  42.           (tex-confirm-visit
  43.             (concat "Check spelling for " fnnd " [SPC=(y)es  DEL=(n)o  RET=(a)ll  ESC=(d)one]? ")))
  44.         (progn
  45.           (find-file fn)
  46.           (message "%s, doing %s..." msg fnnd)
  47.           (sit-for 3)
  48.           (tex-spell-buffer prefix))))))
  49.     (message "%s...done" msg)))
  50.  
  51. (defun tex-spell-buffer (&optional prefix)
  52.   "Check spelling of every word in the buffer.
  53. With prefix argument, check spelling using a customized hashed spelling list,
  54. if any, without query.  A customized hashed spelling list is either current
  55. document master filename base concatenated with \".hsl\", or the file
  56. bound to the variable tex-hsl-default."
  57.   (interactive "P")
  58.   (tex-spell-region prefix 1 (point-max) (buffer-name)))
  59.  
  60. (defun tex-spell-region (&optional prefix start end &optional description)
  61.   "Like tex-buffer-spell but applies only to region.
  62. From program, applies from START to END.
  63. With prefix argument, check spelling using a customized hashed spelling list,
  64. if any, without query.  A customized hashed spelling list is either current
  65. document master filename base concatenated with \".hsl\", or the file
  66. bound to the variable tex-hsl-default."
  67.   (interactive "P\nr")
  68.   (let ((sm (set-marker (make-marker) start))
  69.     (em (set-marker (make-marker) end)))
  70.     (tex-check-document-type)
  71.     (tex-check-master-file)            ; defined in TeX-misc.el
  72.     (if (file-exists-p tex-spell-filter)
  73.       nil
  74.       (error "Spelling filter \"%s\" does not exist" tex-spell-filter))
  75.     (save-window-excursion
  76.       (let ((=err= (get-buffer-create tex-spell-error-buff))
  77.         (=cmd= (get-buffer-create "*Shell Command Output*"))
  78.         (=buff= (current-buffer))
  79.         (=fn= (buffer-file-name))
  80.         (=msgs= (concat "Checking " tex-doc-type " spelling for " (or description "region")))
  81.         speller)
  82.     (catch 'all-done
  83.       (while t
  84.         (setq start (marker-position sm))
  85.         (setq end (marker-position em))
  86.         (setq tex-spell-small-window nil)
  87.         (save-excursion
  88.           (set-buffer =err=)
  89.           (widen)
  90.           (erase-buffer))
  91.         (setq speller (tex-spell-get-speller prefix))
  92.         (if (= ?\n (char-after (1- end)))
  93.           (progn
  94.         (call-process-region start end shell-file-name nil =err= nil "-c" tex-spell-filter)
  95.         (save-excursion
  96.           (set-buffer =err=)
  97.           (call-process-region 1 (point-max) shell-file-name t =err= nil "-c" speller)))
  98.           (let ((filter tex-spell-filter)) ; will be nil in =err= if not assgined
  99.         (save-excursion
  100.           (set-buffer =err=)
  101.           (insert-buffer-substring =buff= start end)
  102.           (insert ?\n)
  103.           (call-process-region 1 (point-max) shell-file-name t =err= nil "-c" filter)
  104.           (call-process-region 1 (point-max) shell-file-name t =err= nil "-c" speller))))
  105.         (tex-spell-examine prefix)))))))
  106.        
  107. (defun tex-spell-examine (prefix)
  108.   (let ((case-fold-search t)
  109.     (case-replace t)
  110.     (down t)
  111.     (first t)
  112.     (master tex-master-file)
  113.     word msgs reg-word new-word selected-word
  114.     cmd next-cmd last-pos old-pos)
  115.     (if (save-excursion
  116.       (set-buffer =err=)
  117.       (goto-char 1)
  118.       (> (buffer-size) 0))
  119.       (progn
  120.     (while (save-excursion
  121.          (if tex-spell-small-window
  122.            (progn
  123.              (delete-window)
  124.              (other-window -1)
  125.              (enlarge-window tex-slow-win-lines)
  126.              (setq tex-spell-small-window nil)))
  127.          (set-buffer =err=)
  128.          (not (or (= (buffer-size) 0)
  129.               (and down 
  130.                    (eobp)
  131.                    (if (tex-spell-exit master "next")
  132.                  t
  133.                  (previous-line 1)
  134.                  nil))
  135.               (and (not down)
  136.                    first
  137.                    (tex-spell-exit master "previous")))))
  138.       (save-excursion
  139.         (set-buffer =err=)
  140.         (setq word (buffer-substring (point) (save-excursion (end-of-line) (point)))))
  141.       (tex-spell-get-cmd))
  142. ;;    (if (and (buffer-modified-p) (y-or-n-p (concat "Save file " =fn= "? ")))
  143. ;;      (write-file =fn=))
  144.     (if (y-or-n-p (concat =msgs= ", try again? "))
  145.       t
  146.       (message "%s...done" =msgs=)
  147.       (throw 'all-done t)))
  148.       (message "%s...done (no errors found)" =msgs=)
  149.       (throw 'all-done t))))
  150.  
  151. (defun tex-spell-get-cmd ()
  152.   (setq msgs (concat "Erroneous `" word "' [SPC  DEL  n  p  r  R  w  C-r  ?=help]"))
  153.   (setq reg-word (concat "\\b" (regexp-quote word) "\\b"))
  154.   (setq last-pos (goto-char start))
  155.   (setq next-cmd t)
  156.   (setq selected-word nil)
  157.   (catch 'get-cmd
  158.     (while t
  159.       (if next-cmd
  160.     (progn
  161.       (message msgs)
  162.       (setq cmd (read-char))))
  163.     (setq next-cmd t)
  164.       (cond
  165.     ((= cmd ? )            ; Ignore and goto next error
  166.      (save-excursion
  167.        (set-buffer =err=)
  168.        (next-line 1)
  169.        (setq first nil)
  170.        (setq down t))
  171.      (throw 'get-cmd t))
  172.     ((= cmd ?\177)         ; Ignore and goto previous
  173.      (save-excursion
  174.        (set-buffer =err=)
  175.        (if (bobp)
  176.          (setq first t)
  177.          (previous-line 1))
  178.        (setq down nil))
  179.      (throw 'get-cmd t))
  180.     ((= cmd ?n)                        ; Next instance
  181.      (setq old-pos (point))
  182.      (goto-char last-pos)
  183.      (if (tex-spell-search reg-word end)
  184.        (progn
  185.          (setq last-pos (point))
  186.          (goto-char (match-beginning 0)))
  187.        (goto-char old-pos)
  188.        (message "Wrapping around...")
  189.        (sit-for 1)
  190.        (goto-char start)            ; Wrap-around
  191.        (tex-spell-search reg-word end)      ; Must be there
  192.        (setq last-pos (point))
  193.        (goto-char (match-beginning 0))))
  194.     ((= cmd ?p)                          ; Previous instance
  195.      (if (tex-spell-search reg-word start t)    ; Backward
  196.        (save-excursion
  197.          (goto-char (match-end 0))
  198.          (setq last-pos (point)))
  199.        (message "Wrapping around...")
  200.        (sit-for 1)
  201.        (goto-char end)            ; Wrap-around
  202.        (tex-spell-search reg-word start t)    ; Must be there
  203.        (save-excursion
  204.          (goto-char (match-end 0))
  205.          (setq last-pos (point)))))
  206.     ((= cmd ?r)                           ; Replace with word
  207.      (setq new-word (read-string
  208.               (concat "Replacing `" word "' by: ")
  209.               word))
  210.      (save-excursion
  211.        (catch 'abort
  212.          (tex-spell-replace 'abort end reg-word word new-word t)
  213.          (save-excursion
  214.            (set-buffer =err=)
  215.            (delete-region (point) (progn (next-line 1) (point)))
  216.            (if (bobp) (setq down t)))
  217.          (throw 'get-cmd t))))
  218.     ((= cmd ?R)                         ; Replace w/o word
  219.      (setq new-word (read-string 
  220.               (concat "Replacing `" word "' by: ")
  221.               selected-word))
  222.      (save-excursion
  223.        (catch 'abort
  224.          (tex-spell-replace 'abort end reg-word word new-word t)
  225.          (save-excursion
  226.            (set-buffer =err=)
  227.            (delete-region (point) (progn (next-line 1) (point)))
  228.            (if (bobp) (setq down t)))
  229.          (throw 'get-cmd t))))
  230.     ((= cmd ?w)              ; Dictionary lookup
  231.      (catch 'abort
  232.        (tex-spell-word word 'abort)))
  233.     ((= cmd ?\^r)
  234.      (message "Entering recursive edit...(return to spelling checking by ESC C-c)")
  235.      (let ((win (get-buffer-window tex-spell-dict-buff)))
  236.        (if win
  237.          (let ((pos (point)) left)
  238.            (pop-to-buffer tex-spell-dict-buff)
  239.            (recursive-edit)
  240.            (if (eq win (get-buffer-window (buffer-name)))
  241.          (progn
  242.            (save-excursion
  243.              (forward-word 1)
  244.              (backward-word 1)
  245.              (setq left (point)))
  246.            (backward-word 1)
  247.            (insert ?[)
  248.            (setq left (point))
  249.            (forward-word 1)
  250.            (setq selected-word (buffer-substring left (point)))
  251.            (insert ?])
  252.            (pop-to-buffer =buff=)
  253.            (setq next-cmd nil)
  254.            (message msgs)
  255.            (setq cmd (read-char))
  256.            (pop-to-buffer tex-spell-dict-buff)
  257.            (delete-window))))
  258.          (recursive-edit))))
  259.     ((= cmd ??)
  260.      (save-window-excursion
  261.        (tex-spell-help)
  262.        (setq next-cmd nil)
  263.        (message msgs)
  264.        (setq cmd (read-char))))
  265.     (t
  266.      (ding)
  267.      (message "%s...WHAT?" msgs)
  268.      (sit-for 1))))))
  269.  
  270. (defun tex-spell-help ()
  271.   (pop-to-buffer tex-spell-help-buff)
  272.   (if (> (buffer-size) 0)
  273.     nil
  274.     (insert-string
  275. "SPC -- Ignore current erroneous word, try next error, if any.
  276. DEL -- Ignore current erroneous word and try the previous, if any. 
  277.   n -- Go to next instance of the word in buffer, wrap around if necessary.
  278.   p -- Go to previous instance of the word in buffer, wrap around if necessary.
  279.   r -- Replace all instances of the word below dot.
  280.        A repetition of current erroneous word appears at replacement prompt.
  281.   R -- Replace all instances of the word below dot.
  282.        If a word is selected in --- TeX Dictionary ---, it is repeated at 
  283.        prompt; otherwise nothing is repeated.
  284.   w -- Dictionary lookup for words containing the specified substring.
  285.        Result displayed in the other window called --- TeX Dictionary ---.
  286. C-r -- Enter recursive edit.  Return to spelling checking by ESC C-c.
  287.   ? -- This help message.
  288. C-g -- Abort to top level."))
  289.   (enlarge-window (- 15 (window-height)))
  290.   (goto-char 1)
  291.   (other-window 1))
  292.       
  293. (defun tex-spell-exit (master scroll)
  294.   (let (cmd)
  295.     (catch 'done
  296.       (while t
  297.     (message "No more %s entry, exit? [SPC=(y)es  DEL=(n)o  RET=(s)ave]" scroll)
  298.     (setq cmd (read-char))
  299.         (cond ((or (= cmd ? ) (= cmd ?y))
  300.            (throw 'done t))
  301.           ((or (= cmd ?\177) (= cmd ?n))
  302.            (throw 'done nil))
  303.           ((or (= cmd ?\r) (= cmd ?s))
  304.            (tex-spell-save-hsl master)
  305.            (throw 'done t))
  306.           (t
  307.            (setq cmd nil)
  308.            (ding)
  309.            (message "No more %s entry, exit? (SPC/y  DEL/n  RET/s)...WHAT?" scroll)
  310.            (sit-for 1)))))))
  311.  
  312. (defun tex-spell-check-hsl (fn fnnd msgs)
  313.   (save-excursion
  314.     (message "%s, verifying spelling list %s..." msgs fnnd)
  315.     (set-buffer =cmd=)
  316.     (erase-buffer)
  317.     (call-process shell-file-name nil t nil "-c" (concat "echo \"am\" | spellout " fn))
  318.     (if (= (buffer-size) 0)
  319.       t
  320.       (message "Spelling list is corrupted, type any key to continue" fnnd)
  321.       (read-char)
  322.       (message "Removing corrupted spelling list %s..." fn)
  323.       (shell-command (concat "rm " fn))
  324.       (message "Removing corrupted spelling list %s...done" fn)
  325.       (sit-for 3)
  326.       (message "%s..." msgs)
  327.       nil)))
  328.  
  329. (defun tex-spell-get-speller (prefix)
  330.    "Make a hashed spelling list."
  331.    (let* ((hl (tex-spell-ext =fn= tex-spell-hsl-suffix))
  332.       (hlnd (file-name-nondirectory hl))
  333.           (ul (tex-spell-ext =fn= tex-spell-usl-suffix))
  334.       (ulnd (file-name-nondirectory ul))
  335.       (default ""))
  336.      (if (and (or (file-exists-p hl)
  337.           (and tex-hsl-default
  338.                (file-exists-p
  339.              (setq hl (expand-file-name tex-hsl-default)))
  340.                    (setq hlnd (file-name-nondirectory hl))))
  341.           (file-newer-than-file-p hl ul)
  342.           (or prefix
  343.               (y-or-n-p (concat "Use " hlnd " as hashed spelling list? ")))
  344.           (tex-spell-check-hsl hl hlnd =msgs=))
  345.        (progn
  346.      (message "%s, using %s as spelling list..." =msgs= (file-name-nondirectory hl))
  347.          (concat tex-speller " -d " hl))
  348.        (if (and (or (file-exists-p ul)
  349.             (and tex-usl-default
  350.              (file-exists-p
  351.                (setq ul (expand-file-name tex-usl-default)))
  352.              (setq ulnd (file-name-nondirectory ul))))
  353.         (or prefix
  354.             (y-or-n-p (concat "Use " ulnd " as unhashed spelling list? "))))
  355.      (progn
  356.        (message "%s, creating %s from %s..." =msgs= hlnd ulnd)
  357.        (if (and tex-usl-default (file-exists-p tex-usl-default))
  358.          (setq default tex-usl-default))
  359.        (call-process shell-file-name nil =cmd= nil "-c"
  360.          (concat "cat " ul " " default "|" tex-spellout " " tex-hsl-global
  361.              "|" tex-spellin " " tex-hsl-global ">" hl))
  362.        (message "%s, using %s as spelling list..." =msgs= hlnd)
  363.        (concat tex-speller " -d " hl))
  364.      (message "%s..." =msgs=)
  365.      tex-speller))))
  366.  
  367. (defun tex-spell-ext (fn suffix)
  368.   (let* ((fnnd (file-name-nondirectory fn))
  369.      (dir (file-name-directory fn))
  370.      (pos (string-match "\\." fnnd)))
  371.     (if (and pos (> pos 0))
  372.       (concat (or dir "") (substring fnnd 0 pos) suffix)
  373.       (concat fn suffix))))
  374.  
  375. (defun tex-spell-check-words ()
  376.   (if (save-excursion
  377.     (set-buffer =err=)
  378.     (goto-char 1)
  379.     (> (buffer-size) 0))
  380.     (if (y-or-n-p "Reexamine uncorrected words before saving? ")
  381.       (let (word msgs cmd next-cmd)
  382.     (save-excursion
  383.       (set-buffer =err=)
  384.       (goto-char 1)
  385.       (catch 'checked
  386.         (while (> (buffer-size) 0)
  387.           (beginning-of-line)
  388.           (if (eobp)
  389.         (if (y-or-n-p "No more next word, done? ")
  390.           (throw 'checked t)
  391.           (previous-line 1)))
  392.           (setq word (buffer-substring
  393.                (point) (save-excursion (end-of-line) (point))))
  394.           (if (string-equal word "")
  395.         (kill-line 1))
  396.           (tex-spell-cw-cmd))
  397.         (message "No uncorrected words left.")
  398.         (sit-for 3)
  399.         (throw 'done t)))))
  400.     (message "No uncorrected words left.")
  401.     (sit-for 3)
  402.     (throw 'done t)))
  403.  
  404. (defun tex-spell-cw-cmd ()
  405.   (setq msgs (concat "Looking at `" word "'  [SPC=(n)ext  DEL=(p)revious  RET=(r)emove  ESC=(d)one]"))
  406.   (catch 'get-cmd
  407.     (while t
  408.       (message msgs)
  409.       (setq next-cmd t)
  410.       (setq cmd (read-char))
  411.       (cond
  412.     ((or (= cmd ? ) (= cmd ?n))            ; Ignore and goto next error
  413.      (next-line 1))
  414.     ((or (= cmd ?\177) (= cmd ?p))        ; Ignore and goto previous
  415.      (if (bobp)
  416.        (if (y-or-n-p "No more previous word, done? ")
  417.          (throw 'checked t))
  418.        (previous-line 1)))
  419.     ((or (= cmd ?\r) (= cmd ?r))
  420.      (kill-line 1)
  421.      (if (eobp)
  422.        (previous-line 1)))
  423.     ((or (= cmd ?\e) (= cmd ?d))
  424.      (throw 'checked t))
  425.     (t
  426.      (setq next-cmd nil)
  427.      (ding)
  428.      (message "%s...WHAT?" msgs)
  429.      (sit-for 1)))
  430.       (if next-cmd
  431.     (throw 'get-cmd t)))))
  432.   
  433. (defun tex-spell-save-hsl (master)
  434.   (tex-spell-check-words)
  435.   (let* ((hl (tex-spell-ext master tex-spell-hsl-suffix))
  436.      (hlnd (file-name-nondirectory hl))
  437.      (hl-p (file-exists-p hl))
  438.      (ul (tex-spell-ext master tex-spell-usl-suffix))
  439.      (ulnd (file-name-nondirectory ul))
  440.      (ul-p (file-exists-p ul))
  441.      (newer (file-newer-than-file-p hl ul))
  442.      (hl-g (and hl-p
  443.             (tex-spell-check-hsl hl hlnd "Saving spelling list")))
  444.      (default ""))
  445.     (if ul-p
  446.       (progn
  447.     (message "Extending unhashed spelling list %s..." ulnd)
  448.     (call-process-region 1 (point-max) shell-file-name nil =cmd= nil "-c"
  449.       (concat "sort -u " ul "> /tmp/" ulnd "; mv /tmp/" ulnd " ."))
  450.     (message "Extending unhashed spelling list %s...done" ulnd))
  451.       (message "Creating unhashed spelling list %s..." ulnd)
  452.       (write-region 1 (point-max) ul nil 'no-message)
  453.       (message "Creating unhashed spelling list %s...done" ulnd))
  454.     (if (and newer hl-g)
  455.      (progn
  456.        (message "Extending hashed spelling list %s..." hlnd)
  457.        (call-process-region 1 (point-max) shell-file-name nil =cmd= nil "-c"
  458.      (concat "cat |" tex-spellout " " hl "|" tex-spellin " " hl
  459.            ">" "/tmp/" hlnd "; mv /tmp/" hlnd " ."))
  460.        (message "Extending hashed spelling list %s...done" hlnd)
  461.        (sit-for 3))
  462.      (message "Creating hashed spelling list %s from %s..." hlnd ulnd)
  463.      (if (and tex-usl-default (file-exists-p tex-usl-default))
  464.        (setq default tex-usl-default))
  465.      (call-process shell-file-name nil =cmd= nil "-c"
  466.        (concat "cat " ul " " default "|" tex-spellout " " tex-hsl-global
  467.            "|" tex-spellin " " tex-hsl-global ">" hl))
  468.      (message "Creating hashed spelling list %s from %s...done" hlnd ulnd)
  469.      (sit-for 3))))
  470.  
  471. (defun tex-spell-word (&optional pre &optional abort)
  472.   "Check the spelling of a word.  If PRE is non-nil, use it as default.
  473. If pre is a non-string and is set by prefix argument, then use the
  474. preceding word as default."
  475.   (interactive "P")
  476.   (let ((old (current-buffer))
  477.     (tmp (get-buffer-create tex-spell-dict-buff))
  478.     (offset 0)
  479.     (dict nil)
  480.     key m i fix prefix suffix msg bow)
  481.     (catch 'loop
  482.       (while t
  483.         (message "Lookup string as prefix, infix, or suffix? (RET/p i s)")
  484.     (setq fix (read-char))
  485.     (cond
  486.       ((or (= fix ?\r) (= fix ?p))
  487.        (setq prefix "")
  488.        (setq suffix "")
  489.        (setq fix "prefix")
  490.        (throw 'loop t))
  491.       ((= fix ?i)
  492.        (setq dict t)
  493.        (setq prefix "")
  494.        (setq suffix "")
  495.        (setq fix "infix")
  496.        (throw 'loop t))
  497.       ((= fix ?s)
  498.        (setq dict t)
  499.        (setq prefix "^.*")
  500.        (setq suffix "$")
  501.        (setq fix "suffix")
  502.        (throw 'loop t))
  503.       (t
  504.        (ding)
  505.            (message "Lookup string as prefix, infix, or suffix (RET/p i s) WHAT?")
  506.        (sit-for 1)))))
  507.     (if (and pre (not (stringp pre)))
  508.       (save-excursion
  509.     (backward-word 1)
  510.         (setq bow (point))
  511.     (forward-word 1)
  512.     (setq pre (buffer-substring bow (point)))))
  513.     (setq key (read-string (concat "String as " fix ": ") pre))
  514.     (if (string-equal key "")
  515.       (if abort
  516.     (progn
  517.       (ding)
  518.       (message "Don't know how to lookup a null string.")
  519.       (throw abort nil))
  520.         (error "Don't know how to lookup a null string."))
  521.       (setq msg (concat "Looking up `" key "' as " fix " in \"" tex-dictionary "\"..."))
  522.       (setq key (concat prefix key suffix)))
  523.     (message msg)
  524.     (set-buffer tmp)
  525.     (erase-buffer)
  526.     (if dict
  527.       (call-process tex-egrep nil t nil key tex-dictionary)
  528.       (call-process tex-look nil t nil key))
  529.     (if (= (buffer-size) 0)
  530.       (progn
  531.     (ding)
  532.         (message "%sfailed" msg)
  533.     (sit-for 1))
  534.       (goto-char 1)
  535.       (while (not (eobp))
  536.     (end-of-line)
  537.     (setq offset (max offset (+ (current-column) 5)))
  538.     (next-line 1))
  539.       (setq m (/ (window-width) offset))
  540.       (goto-char 1)
  541.       (while (not (eobp))
  542.     (setq i 1)
  543.     (while (and (< i m) (not (eobp)))
  544.       (end-of-line)
  545.       (delete-char 1)
  546.       (indent-to (1+ (* i offset)))
  547.       (setq i (1+ i)))
  548.     (next-line 1))
  549.       (goto-char 1)
  550.       (pop-to-buffer tmp)
  551.       (message "%sdone" msg))
  552.     (pop-to-buffer old)))
  553.  
  554. (defun tex-spell-replace (cont bound from-regexp from-string to-string query-flag)
  555.   (let ((nocasify (not (and case-fold-search 
  556.                 case-replace
  557.                 (string-equal from-string (downcase from-string)))))
  558.     (literal nil)
  559.     (keep-going t))
  560.     (push-mark)
  561.     (push-mark)
  562.     (while (and keep-going
  563.         (not (eobp))
  564.         (progn
  565.           (set-mark (point))
  566.           (tex-spell-search from-regexp bound)))
  567.       (undo-boundary)
  568.       (if (not query-flag)
  569.       (replace-match to-string nocasify literal)
  570.     (let (done replaced)
  571.       (while (not done)
  572.         (message "Query replacing `%s' with `%s' (^C if to quit prematurely)..." from-string to-string)
  573.         (setq char (read-char))
  574.         (cond
  575.           ((= char ?\^c)
  576.            (ding)
  577.            (message "Quitting query replacing...(return to previous level)")
  578.            (sit-for 1)
  579.            (throw cont nil))
  580.           ((= char ?\e)
  581.            (setq keep-going nil)
  582.            (setq done t))
  583.           ((= char ?^)
  584.            (goto-char (mark))
  585.            (setq replaced t))
  586.           ((= char ?\ )
  587.            (or replaced (replace-match to-string nocasify literal))
  588.            (setq done t))
  589.           ((= char ?\.)
  590.            (or replaced (replace-match to-string nocasify literal))
  591.            (setq keep-going nil)
  592.            (setq done t))
  593.           ((and (not replaced) (= char ?\,))
  594.            (replace-match to-string nocasify literal)
  595.            (setq replaced t))
  596.           ((= char ?!)
  597.            (or replaced (replace-match to-string nocasify literal))
  598.            (setq done t query-flag nil))
  599.           ((= char ?\177)
  600.            (setq done t))
  601.           ((= char ?\^r)
  602.            (store-match-data
  603.          (prog1 (match-data)
  604.             (save-excursion (recursive-edit)))))
  605.           ((= char ?\^w)
  606.            (delete-region (match-beginning 0) (match-end 0))
  607.            (store-match-data
  608.          (prog1 (match-data)
  609.                 (save-excursion (recursive-edit))))
  610.            (setq done t))
  611.           (t
  612.            (setq keep-going nil)
  613.            (setq unread-command-char char)
  614.            (setq done t)))))))
  615.     keep-going))
  616.  
  617. (defvar tex-slow-speed 2400)
  618. (defvar tex-slow-win-lines 1)
  619. (defvar tex-spell-small-window nil "Flag designating small window")
  620. (defvar tex-spell-large-window-begin 0)
  621. (defvar tex-spell-large-window-end 0)
  622.  
  623. (defun tex-spell-search (regexp bound &optional backward)
  624.   (let ((search-fun (if backward 're-search-backward 're-search-forward))
  625.     (slow-terminal-mode (<= (baud-rate) tex-slow-speed))
  626.     (window-min-height (min window-min-height (1+ tex-slow-win-lines)))
  627.     (found-dot nil))    ; to restore dot from a small window
  628.     (if (funcall search-fun regexp bound t)
  629.       (progn
  630.         (setq found-dot (point))
  631.         (if (not tex-spell-small-window)
  632.       (progn
  633.         (setq tex-spell-large-window-begin 
  634.           (save-excursion 
  635.         (move-to-window-line 0)
  636.         (beginning-of-line)
  637.         (point)))
  638.         (setq tex-spell-large-window-end
  639.           (save-excursion 
  640.         (move-to-window-line -1)
  641.         (end-of-line)
  642.         (point)))))
  643.         (if (and slow-terminal-mode
  644.          (not (or tex-spell-small-window (pos-visible-in-window-p))))
  645.       (progn
  646.         (setq tex-spell-small-window t)
  647.         (move-to-window-line 0)
  648.         (split-window nil (- (window-height) (1+ tex-slow-win-lines)))
  649.         (other-window 1)))
  650.     (goto-char found-dot)
  651.     (if (and tex-spell-small-window
  652.          (>= found-dot tex-spell-large-window-begin)
  653.          (<= found-dot tex-spell-large-window-end))
  654.       (progn
  655.         (setq tex-spell-small-window nil)
  656.         (delete-window)
  657.         (other-window -1)
  658.         (enlarge-window tex-slow-win-lines)
  659.         (goto-char found-dot)))
  660.      t))))
  661.